import flet as ft
import logging
from logging.handlers import QueueHandler
from queue import Queue
import threading
import time
import sys
from io import StringIO
import webbrowser
import pyautogui
import pyperclip
import keyboard
from pathlib import Path

# 添加自定义模块路径
sys.path.append(str(Path(__file__).parent / 'src'))
from AutomationTool import AutomationTool

# 获取AI提示词
def get_ai_prompt():
    return """# 补充具体操作代码

请根据用户对话内容，在以下代码的基础上补充具体的操作代码，注意每个操作之间默认1s延时，确保上一步骤已完成。
设置用F7热键作为程序停止运行的热键。
AutomationTool类中已经有了日志输出log函数，其各个工具均有对应的日志输出，你认为还需要记录的其他信息（比如循环、运行结束等）可以用log函数进行记录。
尽量使用pyautogu、pypercli、keyboard、pynput模块完成脚本编写，如果需要引入新的模块，请重点提示用户需要安装。import sys
from pathlib import Path
import keyboard
sys.path.append(str(Path(__file__).parent / 'src'))
from AutomationTool import AutomationTool

# 全局变量，用于控制循环是否继续
running = True

def stop_program(e):
    global running
    running = False
    print("检测到 F7 热键，程序即将停止...")
if __name__ == "__main__":
    tool = AutomationTool()
    # 注册 F7 热键监听
    keyboard.on_press_key('f7', stop_program)

    # 在这里补全具体的操作代码

    # 移除热键监听
    keyboard.unhook_all()
以下提供了关于自动化任务的详细描述，包括所需的操作步骤、目标、相关参数等信息。根据这些信息，你需要合理地调用 `AutomationTool` 类中提供的各种函数来实现对应的自动化操作。

`AutomationTool` 类中可用的操作函数及其说明如下：
        | 操作名称         | 函数                       | 需要的参数                          | 参数说明                         | 返回参数                     |
        | --------------- | -------------------------- | ---------------------------------- | ------------------------------ | -------------------------- |
        | 延时等待         | sleep                      | s                                  | 等待时间(秒)                    | bool：操作是否成功          |
        | 按位置点击左键       | click_at_position          | x, y                              | 分开的x和y坐标（整数类型）                     | bool：点击是否成功          |
        | 按位置点击右键       | click_at_position_right    | x, y                              | 分开的x和y坐标（整数类型）                     | bool：点击是否成功          |
        | 鼠标移动到指定位置   | move_to_position           | x, y                              | 分开的x和y坐标（整数类型）                     | bool：移动是否成功          |
        | 按住鼠标按键N秒后松开 | press_mouse_button         | button, seconds=1                 | button：鼠标按键（'left'、'right'或'middle'）；seconds：按住时间（秒） | bool：操作是否成功          |
        | 按住键盘按键N秒后松开 | press_key                  | key, seconds=1                    | key：键盘按键名称；seconds：按住时间（秒）       | bool：操作是否成功          |
        | 文本粘贴         | input_text                 | text                               | 要输入的文本内容                | bool：粘贴是否成功          |
        | 图片识别         | image_recognition          | image_path                        | 图片文件路径                    | (bool, location)：是否识别到及位置 |
        | 图片识别后点击   | click_on_image             | image_path                        | 要识别并点击的图片路径           | bool：点击是否成功          |
        | 模拟组合按键     | hotkey                     | key1, key2                        | 组合键名称(如'ctrl','c')        | bool：按键是否成功          |
        | 模拟单按键       | press                      | key                               | 按键名称(如'enter')             | bool：按键是否成功          |
        | 鼠标滚动         | scroll                     | amount                            | 滚动距离(正数向上，负数向下)    | bool：滚动是否成功          |
        | 鼠标拖拽         | drag                       | start_xy, end_xy, duration=0.5    | 起始坐标(start_x,start_y)，结束坐标(end_x,end_y)，持续时间(秒) | bool：拖拽是否成功          |
        | 截图            | capture_screen             | output_path, region=None          | 保存路径，可选区域(left,top,width,height) | bool：操作是否成功          |
        | 获取鼠标位置     | get_mouse_position         | 无需参数                          | 按下F8热键后获取当前鼠标位置     | (x, y)：鼠标当前位置坐标 |
        | 记录日志         | log                        | content                           | 要记录的日志内容                 | bool：操作是否成功          |

请仔细分析用户对话内容，确定需要执行的操作步骤，并按照上述函数的参数要求，依次调用相应的函数，补充到代码中，以完成整个自动化任务的代码实现。确保代码逻辑清晰、连贯，能够正确地实现用户所期望的自动化操作流程。

现在请你准确理解上述要求，准备好了告我，我将提出具体要求。"""

# 日志处理线程
class LogThread(threading.Thread):
    def __init__(self, log_queue, console_output, page):
        super().__init__()
        self.log_queue = log_queue
        self.console_output = console_output
        self.page = page
        self.running = True

    def run(self):
        while self.running:
            if not self.log_queue.empty():
                record = self.log_queue.get()
                color = "blue" if record.levelno < logging.WARNING else "red"
                # 插入新日志时跳过提示栏
                self.console_output.current.controls.insert(1, ft.Text(f"{record.msg}", color=color))
                
                # 限制日志数量(保留提示栏)
                if len(self.console_output.current.controls) > 101:
                    self.console_output.current.controls.pop()
                self.page.update()
            time.sleep(0.1)

    def stop(self):
        self.running = False

def main(page: ft.Page):
    # 窗口设置
    page.window.width = 500
    page.window.height = 680
    page.title = "⌨️键盘🖱️鼠标自动化"
    page.vertical_alignment = ft.CrossAxisAlignment.START  # 顶部对齐，确保组件按顺序排列
    page.horizontal_alignment = ft.CrossAxisAlignment.CENTER
    page.padding = ft.Padding(10, 10, 10, 10)  # 添加内边距

    # 响应式变量
    py_file_path = ft.Ref[str]()
    console_output = ft.Ref[ft.Column]()
    code_editor = ft.Ref[ft.TextField]()
    mouse_pos_text = ft.Ref[ft.Text]()
    record_button_ref = ft.Ref[ft.ElevatedButton]()
    stop_button_ref = ft.Ref[ft.ElevatedButton]()

    # 文件选择器
    def pick_files_result(e: ft.FilePickerResultEvent):
        if e.files:
            py_file_path.current = e.files[0].path
            file_name.value = e.files[0].name
            page.update()

    pick_files_dialog = ft.FilePicker(on_result=pick_files_result)
    page.overlay.append(pick_files_dialog)
    file_name = ft.Text("未选择文件", size=16)

    # 日志配置
    log_queue = Queue()
    queue_handler = QueueHandler(log_queue)
    queue_handler.setLevel(logging.INFO)
    root_logger = logging.getLogger()
    root_logger.addHandler(queue_handler)
    root_logger.setLevel(logging.INFO)

    # 启动日志线程
    log_thread = LogThread(log_queue, console_output, page)
    log_thread.start()

    # 执行代码的通用函数
    def run_code(code_content):
        # 清空日志时保留提示栏
        console_output.current.controls = console_output.current.controls[:1]
        console_output.current.controls.append(ft.Text("正在执行...", size=14, color="blue"))
        page.update()

        try:
            old_stdout = sys.stdout
            sys.stdout = mystdout = StringIO()
            exec(code_content)
            sys.stdout = old_stdout
            
            output = mystdout.getvalue()
            if output:
                console_output.current.controls.insert(1, ft.Text(output, color="blue"))
        except Exception as e:
            console_output.current.controls.insert(1, ft.Text(f"执行出错: {str(e)}", color="red"))
        finally:
            page.update()

    # 执行文件中的代码
    def execute_code(e):
        if py_file_path.current:
            with open(py_file_path.current, 'r', encoding='utf-8') as file:
                run_code(file.read())

    # 执行粘贴的代码
    def execute_pasted_code(e):
        if code_editor.current.value:
            run_code(code_editor.current.value)
        else:
            console_output.current.controls.insert(1, ft.Text("没有可执行的代码，请先粘贴代码", color="red"))
            page.update()

    # 日志操作（公用功能）
    def copy_console_log(e):
        # 复制日志时排除提示栏
        log_content = '\n'.join([
            c.value for c in console_output.current.controls 
            if isinstance(c, ft.Text) and c.value not in [
                "操作提示: F7停止程序 | F8获取鼠标位置 | 已打包pyautogui、pyperclip等模块",
                "等待日志..."
            ]
        ])
        page.set_clipboard(log_content)

    def clear_console_log(e):
        # 清空日志时保留提示栏
        console_output.current.controls = [
            console_output.current.controls[0],  # 保留提示栏
            ft.Text("等待日志...", size=14, color="gray")
        ]
        page.update()

    # 复制AI提示词
    def copy_ai_prompt(e):
        page.set_clipboard(get_ai_prompt())
        # 可以在这里添加一个提示，告知用户已复制
        console_output.current.controls.insert(1, ft.Text("AI提示词已复制到剪贴板", color="green"))
        page.update()

    # 录制功能（教程标签页中使用）
    tool = AutomationTool(logger=root_logger)

    def start_recording(e):
        tool.start_recording()
        record_button_ref.current.disabled = True
        stop_button_ref.current.disabled = False
        page.update()

    def stop_recording(e):
        tool.stop_recording()
        record_button_ref.current.disabled = False
        stop_button_ref.current.disabled = True
        page.update()

    # 获取鼠标位置
    def get_mouse_position(e):
        x, y = pyautogui.position()
        mouse_pos_text.current.value = f"鼠标: ({x},{y})"
        pyperclip.copy(f"({x},{y})")
        page.update()

    # 注册F8热键
    keyboard.on_press_key('f8', get_mouse_position)

    # 窗口关闭处理
    def on_window_event(e):
        if e.data == 'close':
            log_thread.stop()
            log_thread.join()

    page.on_window_event = on_window_event

    # 构建UI
    page.add(
        ft.Column([
            # 1. 标题（最顶部）
            ft.Text("⌨️键盘🖱️鼠标自动化", size=18, weight="bold"),
            
            # 2. 日志操作行（标题下方）
            ft.Row([
                ft.ElevatedButton("复制日志", on_click=copy_console_log),
                ft.ElevatedButton("清空日志", on_click=clear_console_log),
                ft.ElevatedButton("复制AI提示词", on_click=copy_ai_prompt),
                ft.ElevatedButton(
                    "跳转AI网站",
                    on_click=lambda e: [
                        webbrowser.open("https://www.kimi.com/"),
                        webbrowser.open("https://www.doubao.com//"),
                        webbrowser.open("https://yuanbao.tencent.com/chat/")
                    ]
                ),
            # 鼠标位置显示
            ft.Text(ref=mouse_pos_text, size=12, color="green", value="鼠标: (未获取)"),
            ], alignment=ft.MainAxisAlignment.CENTER),
  
            # 添加分隔线
            ft.Divider(height=2, color="gray"),

            # 4. 日志输出区域（鼠标位置下方）
            ft.Column(
                ref=console_output,
                scroll=ft.ScrollMode.AUTO,
                expand=True,
                height=180,
                controls=[
                    # 操作提示栏(固定在日志区域顶部)
                    ft.Text("操作提示: F7停止程序 | F8复制鼠标坐标 | 已打包pyautogui、pyperclip等模块", 
                           size=12, color=ft.Colors.BLACK),
                    ft.Text("当前版本：20250923 \n 等待日志...", size=14, color="gray")
                ]
            ),

            # 添加分隔线
            ft.Divider(height=2, color="gray"),

            # 5. 三个标签页（日志区域下方）
            ft.Tabs(
                selected_index=0,
                width=530,
                tabs=[
                    # 1. 使用教程标签页
                    ft.Tab(
                        text="使用教程",
                        content=ft.Column([
                            ft.Container(
                                content=ft.Text(
                                    "本工具可通过录制或编写代码实现鼠标键盘自动化操作。\n"
                                    "1.录制：点击开始录制——进行正常操作——点击停止录制\n"
                                    "2.AI辅助：复制日志后，粘贴到AI中，通过对话修正真正的自动化逻辑\n"
                                    "3.编写代码：点击复制AI提示词——粘贴自动化逻辑——得到自动化代码\n"
                                    "4.选择粘贴运行或文件运行：前者适用于一次运行，后者适用于重复运行\n",
                                    size=14
                                ),
                                padding=5,
                                margin=ft.Margin(0, 0, 0, 0),
                                bgcolor=ft.Colors.BLUE_50,
                                border_radius=5
                            ),
                            ft.Row([
                                ft.ElevatedButton(
                                    "开始录制",
                                    icon=ft.Icons.RECORD_VOICE_OVER,
                                    on_click=start_recording,
                                    ref=record_button_ref
                                ),
                                ft.ElevatedButton(
                                    "停止录制",
                                    icon=ft.Icons.STOP,
                                    on_click=stop_recording,
                                    ref=stop_button_ref,
                                    disabled=True
                                ),
                            ], alignment=ft.MainAxisAlignment.CENTER),
                        ], spacing=8,horizontal_alignment=ft.CrossAxisAlignment.CENTER)
                    ),
                    
                    # 2. 粘贴运行标签页
                    ft.Tab(
                        text="粘贴运行",
                        content=ft.Column([
                            ft.Text("直接粘贴代码并运行", size=12, weight="bold"),
                            # 使用ListView实现滚动功能
                            ft.ListView(
                                controls=[
                                    ft.TextField(
                                        ref=code_editor,
                                        multiline=True,
                                        min_lines=6,
                                        max_lines=10,
                                        width=500,
                                        hint_text="请粘贴你的Python代码到这里...",
                                    )
                                ],
                                height=180,  # 固定高度，超出部分可滚动
                                spacing=0,
                            ),
                            ft.Row([
                                ft.ElevatedButton(
                                    "运行粘贴的代码",
                                    icon=ft.Icons.PLAY_CIRCLE_FILL,
                                    on_click=execute_pasted_code,
                                    color=ft.Colors.BLUE,
                                )
                            ], alignment=ft.MainAxisAlignment.CENTER),
                        ], spacing=10)
                    ),
                        

                    
                    # 3. 文件运行标签页
                    ft.Tab(
                        text="文件运行",
                        content=ft.Column([
                            ft.Text("选择并执行本地脚本文件", size=14, weight="bold"),
                            ft.Row([
                                ft.ElevatedButton(
                                    "选择执行脚本",
                                    icon=ft.Icons.UPLOAD_FILE,
                                    on_click=lambda _: pick_files_dialog.pick_files(
                                        allowed_extensions=["py", "txt", "csv", "json", "xml", "html", "md"],
                                        allow_multiple=False
                                    ),
                                ),
                                ft.ElevatedButton("开始执行", icon=ft.Icons.PLAY_ARROW, on_click=execute_code),
                            ], alignment=ft.MainAxisAlignment.CENTER),
                            ft.Container(
                                content=file_name,
                                margin=ft.Margin(0, 10, 0, 0)
                            )
                        ], spacing=10)
                    )
                ]
            ),
            
            # 6. 版本信息（最底部）
            ft.Text("版本: 20250923", size=12, color=ft.Colors.GREY),
        ], 
        spacing=15,  # 控制各组件之间的垂直间距
        width=550,
        tight=True  # 确保Column不会拉伸子组件
        )
    )

if __name__ == "__main__":
    ft.app(target=main)
